package com.jenkins.test.config;

import com.jenkins.test.response.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.UnexpectedTypeException;
import java.nio.file.AccessDeniedException;
import java.sql.SQLException;
import java.util.List;
import java.util.Objects;

/**
 * @version V1.0.0
 * @ClassName: {@link Result}
 * @Description: 全局异常处理
 * {@link RestController}
 * @author: 兰州
 * @date: 2019/7/16 9:22
 * @Copyright: @2019 All rights reserved.
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {


    /**
     * 参数绑定报错消息
     *
     * @param bindException
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = BindException.class)
    public Result<String> bindException(BindException bindException) {
        List<ObjectError> errors = bindException.getBindingResult().getAllErrors();
        return Result.fail("参数错误：" + errors.get(0).getDefaultMessage());
    }

    /**
     * 全局异常捕捉处理
     *
     * @param req
     * @return
     */
    @ExceptionHandler
    public Result<String> handler(HttpServletRequest req, HttpServletResponse res, Exception e) {
        log.info("Restful Http请求发生异常...");
        String message = "网络异常, 请稍后重试";
        if (res.getStatus() == HttpStatus.BAD_REQUEST.value()) {
            log.info("修改返回状态值为200");
            res.setStatus(HttpStatus.OK.value());
        }
        if (e instanceof NullPointerException) {
            log.error("代码00：" + e.getMessage(), e);
        } else if (e instanceof IllegalArgumentException) {
            log.error("代码01：" + e.getMessage(), e);
            message = "请求参数类型不匹配";
        } else if (e instanceof SQLException) {
            log.error("代码02：" + e.getMessage(), e);
            message = "数据库访问异常";
        } else if (e instanceof BindException) {
            BindingResult bindingResult = ((BindException) e).getBindingResult();
            log.error("代码03: BindException ===> " + bindingResult);
            message = "输入参数有误：" + Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage();
        } else if (e instanceof MethodArgumentNotValidException) {
            BindingResult bindingResult = ((MethodArgumentNotValidException) e).getBindingResult();
            log.error("代码04: BBindException ===> " + bindingResult);
            message = "输入参数有误：" + Objects.requireNonNull(bindingResult.getFieldError()).getDefaultMessage();
        } else {
            log.error("代码99：", e);
            message = "服务器代码发生异常,请联系管理员";
        }
        return Result.fail(message);
    }

    /**
     * 未授权
     *
     * @param request
     * @param e
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = {AccessDeniedException.class})
    public Result<String> unauthorizedExceptionHandler(HttpServletRequest request, Exception e) {
        return Result.unauthorized("暂无权限");
    }

}
